package cz.cvut.fel.taskpro.business.imanager;

import cz.cvut.fel.taskpro.business.isupport.IBusinessRuleValidator;
import cz.cvut.fel.taskpro.business.isupport.IMail;
import cz.cvut.fel.taskpro.business.support.BusinessRuleException;
import cz.cvut.fel.taskpro.business.support.TaskProException;
import cz.cvut.fel.taskpro.data.entity.Assignment;
import cz.cvut.fel.taskpro.data.entity.AssignmentSubmit;
import cz.cvut.fel.taskpro.data.entity.Kantor;
import cz.cvut.fel.taskpro.data.entity.Student;
import cz.cvut.fel.taskpro.data.entity.Subject;
import cz.cvut.fel.taskpro.data.entity.Template;
import cz.cvut.fel.taskpro.data.entity.TemplateFile;
import cz.cvut.fel.taskpro.data.entity.Version;
import cz.cvut.fel.taskpro.data.imanager.IAssignmentData;
import java.util.List;
import javax.ejb.Local;

/**
 * This local interface specify responsible action of business manager, which is
 * responsible for working with assignemts, templates and submitted assignments.
 *
 * @author Tom
 * @version 1.0.0. beta
 */
@Local
public interface IAssignmentBusiness {

    /**
     * This method ask data layer for persist new template, if new template pass
     * business validation process. If template is in incompatible state then
     * BusinessRuleException is invoke.
     *
     * @param newTemplate template to add to DB
     */
    public void addTemplate(Template newTemplate) throws BusinessRuleException;

    public Template getTemplateById(long id);

    /**
     * The method ask data layer for all templates which were created by kantor
     * in parameter
     *
     * @param kantor which create template
     * @return <code>List</code> of templates which were created by kantor in parameter
     */
    public List<Template> getTemplateByKantor(Kantor kantor);
    /**
     * This method ask dataLayer for remove template in parameter if template pass 
     * throught business validation procedure.If template is in incompatible state then
     * BusinessRuleException is invoke.
     * @see IBusinessRuleValidator#validateRemove(cz.cvut.fel.taskpro.data.entity.Template) 
     * @see IAssignmentData#removeTemplate(cz.cvut.fel.taskpro.data.entity.Template) 
     * 
     * 
     * @param template to remove
     */
    public void removeTemplate(Template template) throws BusinessRuleException;

    /**
     * This mtehod ask dataLayer to modify template, if template pass throught validation.
     * If template are added then are created new templateFiles. If template does not
     * contain files which were in origin template, then this files are removed from database.
     * 
     * @param originFiles original files with template
     * @param template template to update with new files
     * @see IBusinessRuleValidator#validateUpdate(cz.cvut.fel.taskpro.data.entity.Template) 
     */
    public void modifyTemplate(Template template, List<TemplateFile> originFiles) throws BusinessRuleException;
    /**
     * This method create new assignmets which are specify in parameter. Each assignment 
     * must pass throught validation.
     * If notifyUser is set to true, then mail service will be asked to notify users.
     * @param assignments new assignments to create
     * @param notifyUsers condition if mail service will be asked to notify target users
     * @see IBusinessRuleValidator#validate(cz.cvut.fel.taskpro.data.entity.Assignment) 
     * @see IAssignmentData#assignTemplate(java.util.List) 
     * @see IMail#notifyNewAssignment(java.util.List, java.util.List) 
     */
    public void createAssignments(List<Assignment> assignments, boolean notifyUsers) throws BusinessRuleException, TaskProException;
    /**
     * This method submit new version of assignment. Version must containt that assignments.
     * First validation is made, then is found this submitted assignemt in database via data service layer.
     * If this assigmentis found then new version is simply added, otherwise new assignemnt submit is created
     * and then new version is added. After these action the mail service is asked to 
     * notify kantor of new submitted assignemnt.
     * @param versionOfTask new version of submitted task, if task has not been submitted yet,
     * the new assignemnt submit is created
     * @see IBusinessRuleValidator#validate(cz.cvut.fel.taskpro.data.entity.Version) 
     * @see IBusinessRuleValidator#validateSubmitTask(cz.cvut.fel.taskpro.data.entity.AssignmentSubmit) 
     * @see IMail#notifySendedAssignment(cz.cvut.fel.taskpro.data.entity.Kantor, cz.cvut.fel.taskpro.data.entity.AssignmentSubmit)  
     */
    public void submitAssignments(Version versionOfTask) throws BusinessRuleException, TaskProException;
    /**
     * This method construct all assingments, which can submit student in parameter.
     * First student must pass throught validation, if not then BusinessRuleException is invoke
     * @param student which assignments to submit will be found
     * @return <code>List</code> of all assingments, which can submit student in parameter. If no result is found 
     * then empty list is returned.
     * @see IAssignmentData#assignmentToSubmit(cz.cvut.fel.taskpro.data.entity.Student) 
     */
    public List<Assignment> getAssignmentsToSubmit(Student student) throws BusinessRuleException;
    /**
     * This method ask data layer for all submitted assignments to rate. First students
     * and subjects must pass througth business validator, otherwise businessRuleException is invoke.
     * Then is ask data layer for all team and personal submitted assignment depedn on paramters.
     * For detail behavior of data layer see
     * @see IAssignmentData#getAssignmentSubmitsByKontext(cz.cvut.fel.taskpro.data.entity.Kantor, java.util.List, java.util.List) 
     * @see IAssignmentData#getAssignmentTeamToRateByContext(java.util.List, java.util.List, java.util.List) 
     * @param mStudents students which submitted assigmnets
     * @param subjects subjects in which assignment were submitted
     * @param states of submitted assignmnents
     * @return <code>List</code> of all submitted assignments to rate. If subject or state are null, then 
     * are not taken as condition during search in data layer.
     */
    
    public List<AssignmentSubmit> getAssignmentsToRateByContext(List<Student> mStudents, List<Subject> subjects,
            List<AssignmentSubmit.State> states) throws BusinessRuleException;
    
      /**
     * This method ask data layer for all submitted assignments which has specify type. First students
     * must pass througth business validator, otherwise businessRuleException is invoke.
     * Then is ask data layer for all team and personal submitted assignment depedn on paramters.
     * For detail behavior of data layer see
     * @see IAssignmentData#getAssignmentSubmitsByKontext(cz.cvut.fel.taskpro.data.entity.Kantor, java.util.List, java.util.List) 
     * @see IAssignmentData#getAssignmentTeamToRateByContext(java.util.List, java.util.List, java.util.List) 
     * @param student students which submitted assigmnets
     * @param subjects subjects in which assignment were submitted
     * @param stateOfSubmit state of submitted assignmnents
     * @param typeOfAssignment type of submitted assignmets
     * @return <code>List</code> of all submitted assignments to rate. If subject or state or type
     * are null or empty then then empty list is returned.
     */
    public List<AssignmentSubmit> getAssignmentSubmitsByContext(Student student, List<Subject> subjects,
            List<AssignmentSubmit.State> stateOfSubmit, List<Assignment.Type> typeOfAssignment) throws BusinessRuleException;
     /**
     * This method ranked submitted assignemnt. First validation is necessary.
     * If past throught validation then is asked data layer for update assignment 
     * and then users are notified via mail service. Othervise BusinessRuleException
     * is invoke. The date of evaluation is modified.
     * @param taskToRate  submitted task to rank
     * @see IBusinessRuleValidator#validateRate(cz.cvut.fel.taskpro.data.entity.AssignmentSubmit) 
     * @see IMail#notifyRateUser(cz.cvut.fel.taskpro.data.entity.Kantor, cz.cvut.fel.taskpro.data.entity.AssignmentSubmit) 
     */
    public void rateTask(AssignmentSubmit taskToRate) throws BusinessRuleException, TaskProException;
    /**
     * This method ask dataLayer for assignments which are characterized by parameters.
     * If unSubmitTask is true then unsubmit assignmets are founded.
     * If submiTask is true then submit assignments are founded. Both combination is acceptable
     * Next criteria is type. All assignmnets must be assigned to student or his team, depend on type.
     * @param currStudent student whose assignment we want to find
     * @param states states of assignments which we want to find
     * @param submitTask if we want find submitted assigments
     * @param unSubmitTask if we want to fin unsubmitted assignments
     * @param types which type of assignments we want to find
     * @return <code>List</code> of all assignements depend on filter.If unSubmitTask is true then unsubmit assignmets are founded.
     * If submiTask is true then submit assignments are founded. Both combination is acceptable
     * Next criteria is type. All assignmnets must be assigned to student or his team, depend on type.
     * @see IAssignmentData#getAssignmentSubByContext(cz.cvut.fel.taskpro.data.entity.Student, java.util.List, boolean) 
     * @see IAssignmentData#getUnSubmitAssingnment(cz.cvut.fel.taskpro.data.entity.Student, boolean, cz.cvut.fel.taskpro.data.entity.Subject) 
     * @see IAssignmentData#getAssignmentSubByTeam(cz.cvut.fel.taskpro.data.entity.Student, java.util.List, boolean) 
     * @see IAssignmentData#getUnSubmitTeamAssignmet(cz.cvut.fel.taskpro.data.entity.Student, boolean, cz.cvut.fel.taskpro.data.entity.Subject) 
     * 
     */
    public List<Assignment> getAssignmentToSubmitByContextFilter(Student currStudent, List<Assignment.Type> types,
            List<AssignmentSubmit.State> states, boolean submitTask, boolean unSubmitTask);
    /**
     * This method ask data layer for all TEAM assignment which were unsubmit 
     * by student in parameter or his coworker in team on assignmnets which were 
     * assigned in subject in parameter. This method return alse unsubmit assignment whith
     * expired deadline
     * @param studentInTeam student who is part of team which has unsubmit assignment
     * @param subject subject in which was this assingmnet assigned.
     * @return <code>List</code> of all TEAM assignment which were unsubmit 
     * by student in parameter or his coworker in team on assignmnets which were 
     * assigned in subject in parameter. This method return alse unsubmit assignment whith
     * expired deadline
     * @see IAssignmentData#getUnSubmitTeamAssignmet(cz.cvut.fel.taskpro.data.entity.Student, boolean, cz.cvut.fel.taskpro.data.entity.Subject) 
     */
    public List<Assignment> getUnSubmitTeamAssignmet(Student studentInTeam, Subject subject);
 /**
     * This method ask data layer for all GROUP and Personal assignment which were unsubmit 
     * by student in parameter on assignmnets which were 
     * assigned in subject in parameter. This method return alse unsubmit assignment whith
     * expired deadline
     * @param student student who is part of team which has unsubmit assignment
     * @param subject subject in which was this assingmnet assigned.
     * @return <code>List</code> of all GROUP and Personal assignment which were unsubmit 
     * by student in parameter on assignmnets which were 
     * assigned in subject in parameter. This method return alse unsubmit assignment whith
     * expired deadline
     * @see IAssignmentData#getUnSubmitAssignment(java.util.List, cz.cvut.fel.taskpro.data.entity.Student, boolean, cz.cvut.fel.taskpro.data.entity.Subject) 
     * @see IAssignmentData#getUnSubmitAssingnment(cz.cvut.fel.taskpro.data.entity.Student, boolean, cz.cvut.fel.taskpro.data.entity.Subject) 
     */
    public List<Assignment> getUnSubmitPersonalAssignmet(Student student, Subject subject);
    /**
     * This method ask data layer to find all submitted TEAM assignment by studentInParameter,
     * which were assigned in specify subject and has specify state.
     * @param states - state of submitted task, if is null then is not taken as condition.
     * @param studentInTeam - students who is member of team which assingments will be return. Must be not null
     * @param subject -subject in which was assignments assigned. If is null then is not taken as condition
     * @return <code>List</code> of TEAM submitted assignments, which are in specific states, on subjects and was submitted
     * by member of team which is part studdent in parameter.
     * @see IAssignmentData#getAssignmentTeamToRateByContext(java.util.List, java.util.List, java.util.List) 
     */
    public List<AssignmentSubmit> getSubmitTeamAssignmet(Student studentInTeam, List<AssignmentSubmit.State> states, Subject subject);
 /**
     * This method ask data layer to find all submitted GROUP or PERSONAL assignment by studentInParameter,
     * which were assigned in specify subject and has specify state.
     * @param states - state of submitted task, if is null then is not taken as condition.
     * @param student - students who is member of team which assingments will be return. Must be not null
     * @param subject -subject in which was assignments assigned. If is null then is not taken as condition
     * @return <code>List</code> of GROUP or PERSONAL submitted assignments, which are in specific states, on subjects and was submitted
     * by member of team which is part studdent in parameter.
     * @see IAssignmentData#getAssignmentSubmitByContext(java.util.List, java.util.List, java.util.List) 
     */
    public List<AssignmentSubmit> getSubmitPersonalAssignmet(Student student, List<AssignmentSubmit.State> states, Subject subject);
    /**
     * This method ask data layer to find all assignment which were assigned by kantor in parameter 
     * in specific subject. Subjects and kantor are validate via business rule validator.
     * If inconsistent state is indicted, then BusinessRuleExcteption is invoke.
     * @param kantor - kantor who assigned assignments.
     * @param subjects list of subjects in which is kantor part of, and in which was assignment assigned
     * @return <code>List</code> of all asignment which were assigned by kantor in parameter 
     * in specific subject
     * @see IAssignmentData#getAssignmentsByKantorAndSubject(cz.cvut.fel.taskpro.data.entity.Kantor, java.util.List) 
     * @see IBusinessRuleValidator#validate(java.util.List) 
     * @see IBusinessRuleValidator#validate(cz.cvut.fel.taskpro.data.entity.TaskProUser) 
     */
    public List<Assignment> getAssignmetsByKantorSubject(List<Subject> subjects, Kantor kantor) throws BusinessRuleException;
     /**
     * This method ask data layer for update assignement. First this assignment
     * must pass throught validation proces. If not BusinessRuleException is invoke.
     * @param assignment  assignment to update to DB via data layer.
     * If max earned points is changed, then all users have + or - of this changed.
     * Which mean you have 3 points from max 5. Assignments is changed from 5 to 6. 
     * You automaticly get 1 point extra.
     * @see IBusinessRuleValidator#validate(cz.cvut.fel.taskpro.data.entity.Assignment) 
     * @see IAssignmentData#updateAssignment(cz.cvut.fel.taskpro.data.entity.Assignment) 
     */
    public void updateAssignmnet(Assignment assignment) throws BusinessRuleException;
    /**
     * This method ask data layer for finding all submitted assignments, which are
     * part of assignment in parameter. All submited assignments, must have this assignment
     * as his parrent assignment. First business rule validation is necessary. If incosistent
     * state is found then BusinessRuleException is invoke
     * @param assignment assignment which is parent of submitted assignment in return
     * @return <code>List</code> of submitted assignments, which are
     * part of assignment in parameter. All submited assignments, must have this assignment
     * as his parrent assignment.
     * @see IAssignmentData#getAssignmentSubmitsByAssignment(cz.cvut.fel.taskpro.data.entity.Assignment) 
     */
    public List<AssignmentSubmit> getAssignmentSubmitsByAssignment(Assignment assignment) throws BusinessRuleException;

    public List<AssignmentSubmit> getAssignmentSubmitsByKontext(Kantor kantorOnAssignmet, List<Subject> subjects, List<AssignmentSubmit.State> state) throws BusinessRuleException;
    /**
     * This method ask data layer to remove all assignmnets in parameter. Every 
     * assignment must pass throught businesss validation process. If not then businessRuleException 
     * is invoke. All assignments from list are removed or no one.
     * @param assignmentsToRemove list of all assignmets which will be removed
     * 
     */
    public void removeAssignment(List<Assignment> assignmentsToRemove) throws BusinessRuleException;
    /**
     * This method ask data layer for remove assignement. First this assignment
     * must pass throught validation proces. If not BusinessRuleException is invoke.
     * @param assignmentToRemove assignment to remove from DB via data layer
     * @see IBusinessRuleValidator#validateRemove(cz.cvut.fel.taskpro.data.entity.Assignment) 
     * @see IAssignmentData#removeAssignment(cz.cvut.fel.taskpro.data.entity.Assignment) 
     */
    public void removeAssignmen(Assignment assignmentToRemove) throws BusinessRuleException;
}